home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 5791 / 5791.xpi / chrome / flagfox.jar / content / ipdb.js < prev    next >
Text File  |  2009-03-07  |  4KB  |  100 lines

  1. /*
  2.     The IP location database is in the format:
  3.         [4 byte start IP 1][4 byte start IP 2]... [2 byte country code 1][2 byte country code 2]...
  4.         (all IPs from 0x00000000 to 0xFFFFFFFF must exist, with gaps listed as code "??")
  5. */
  6.  
  7. var IPDB_stream = null;
  8. var IPDB_binary = null;
  9. var IPDB_length = 0;
  10.  
  11. function Flagfox_loadIPDB()
  12. {
  13.     const id = "{1018e4d6-728f-4b20-ad56-37578a4de76b}";
  14.     var file = Components.classes["@mozilla.org/extensions/manager;1"]
  15.                          .getService(Components.interfaces.nsIExtensionManager)
  16.                          .getInstallLocation(id)
  17.                          .getItemLocation(id);
  18.     file.append("db.dat");
  19.     if (!file.exists())
  20.         throw "IPDB file not found (" + file.path + ")";
  21.  
  22.     // Open an input stream for file
  23.     // (large JavaScript arrays are slow bloated memory wasters; 30MB+ is ridiculous)
  24.     IPDB_stream = Components.classes["@mozilla.org/network/file-input-stream;1"]
  25.                             .createInstance(Components.interfaces.nsIFileInputStream)
  26.                             .QueryInterface(Components.interfaces.nsISeekableStream);
  27.     IPDB_stream.init(file, 0x01, 0444, 0);  // read-only, read by owner/group/others, normal behavior
  28.     if (!IPDB_stream.available())
  29.         throw "IPDB file failed to load (" + file.path + ")";
  30.  
  31.     // Reading binary needs a helper interface
  32.     IPDB_binary = Components.classes["@mozilla.org/binaryinputstream;1"]
  33.                             .createInstance(Components.interfaces.nsIBinaryInputStream);
  34.     IPDB_binary.setInputStream(IPDB_stream);
  35.  
  36.     IPDB_length = IPDB_stream.available() / 6;   // 4 bytes for IP; 2 bytes for country code
  37.     if (IPDB_length < 80000 || Math.floor(IPDB_length) != IPDB_length)
  38.         throw "IPDB file is corrupt (loaded bytes: " + IPDB_stream.available() + ")";
  39. }
  40.  
  41. function Flagfox_closeIPDB()
  42. {
  43.     if (IPDB_stream != null)
  44.     {
  45.         IPDB_stream.close();
  46.         IPDB_stream = null;
  47.         IPDB_binary = null;
  48.         IPDB_length = 0;
  49.     }
  50. }
  51.  
  52. function Flagfox_lookupIP(ipstring)
  53. {
  54.     function getEntry(index)  // Reading past the end will throw an exception
  55.     {
  56.         IPDB_stream.seek(0,index*4);
  57.         return new Array( IPDB_binary.read32(), IPDB_binary.read32() );  // [start IP, end IP]
  58.     }
  59.  
  60.     function readCountry()  // Finds country code based on current position via last IPDB_getEntry() call
  61.     {
  62.         const IPblock_length = IPDB_length*4;
  63.         IPDB_stream.seek(0,IPblock_length + (IPDB_stream.tell()-8)/2);
  64.         return String.fromCharCode( IPDB_binary.read8(), IPDB_binary.read8() );  // Country code (2 char string)
  65.     }
  66.  
  67.     function dottedquad2long(dottedquad)
  68.     {
  69.         const bytes = dottedquad.split("\.");
  70.         return (16777216 * parseInt(bytes[0])) + (65536 * parseInt(bytes[1])) + (256 * parseInt(bytes[2])) + parseInt(bytes[3]);
  71.     }
  72.  
  73.     function binarySearch(x, low, high)
  74.     {
  75.         if (low > high)
  76.             throw null;
  77.  
  78.         var middle = Math.floor((low + high) / 2);
  79.         var entry = getEntry(middle);
  80.  
  81.         if (entry[0] <= x && x < entry[1])  // entry[1] is start of next range in list; not part of this range
  82.             return entry;
  83.         else if (x < entry[0])
  84.             return binarySearch(x, low, middle-1);
  85.         else  // x >= entry[1]
  86.             return binarySearch(x, middle+1, high);
  87.     }
  88.  
  89.     if (ipstring == "")
  90.         return null;
  91.     try
  92.     {
  93.         binarySearch(dottedquad2long(ipstring), 0, IPDB_length);
  94.         var countrycode = readCountry();
  95.         if (countrycode != "??")  // countrycode "??" indicates a gap in the IPDB
  96.             return new Array( countrycode, countrynames.getString(countrycode) );  // [country code, country name]
  97.     } catch (e) {}
  98.     return null;
  99. }
  100.